﻿using System;
using System.Collections.ObjectModel;
using RegOnline.RegOnlineService;
using RegOnline.Views;

namespace RegOnline
{
    public class MainViewModel : ViewModelBase
    {
        private AppUser currentUser;

        private Group currentGroup;
        private Semestr currentSemestr;
        private UchPlan currentUchPlan;
        private godUP currentGod;
        private TypeSem currenrTypeSem;
        private Discipline currentDiscipline;
        private VidWork currentVidWork;
        private Work currentWork;
        private ReqsWork currentReqWork;
        private RefReq currentRefReq;
        private LoadWork currentLoadWork;


        private bool printFac, printPrepod, printSpec, printKaf;
        public String PrintFacultet, PrintFio, PrintSpec, PrintKaf;


        private static RegOnlineService.RegOnlineDPSClient client = null;
        
        private ObservableCollection<Student> students = new ObservableCollection<Student>();
        private ObservableCollection<Prepod> prepods = new ObservableCollection<Prepod>();
        private ObservableCollection<Group> grups = new ObservableCollection<Group>();
        private ObservableCollection<Semestr> semestrs = new ObservableCollection<Semestr>();
        private ObservableCollection<Work> works = new ObservableCollection<Work>();
        private ObservableCollection<ReqsWork> reqWorks = new ObservableCollection<ReqsWork>();
        private ObservableCollection<RefReq> refReq = new ObservableCollection<RefReq>();
        private ObservableCollection<godUP> gods = new ObservableCollection<godUP>();
        private ObservableCollection<TypeSem> typeSems = new ObservableCollection<TypeSem>();
        private ObservableCollection<Discipline> disciplines = new ObservableCollection<Discipline>();
        private ObservableCollection<VidWork> vidWorks = new ObservableCollection<VidWork>();
        private ObservableCollection<LoadWork> loadWorks = new ObservableCollection<LoadWork>();
   

        public event EventHandler UserLoaded;
        public event EventHandler PrepodsLoaded;
        public event EventHandler StudentLoaded;
        public event EventHandler GroupLoaded;
        public event EventHandler SemetrLoaded;
        public event EventHandler WorksLoaded;
        public event EventHandler ReqWorksLoaded;
        public event EventHandler RefReqLoaded;
        public event EventHandler PrepodGrupsLoaded;
        public event EventHandler GodsLoaded;
        public event EventHandler TypeSemLoaded;
        public event EventHandler DisciplineLoaded;
        public event EventHandler VidWorkLoaded;
        public event EventHandler FileSaved;
        public event EventHandler PrintInfoLoaded;




        public event EventHandler RefReqIserted;
        public event EventHandler ReqWorkIserted;



        public ObservableCollection<Student> Students {get {return students;}}
        public ObservableCollection<Prepod> Predods {get {return prepods;}}
        public ObservableCollection<Group> Groups { get { return grups; } }
        public ObservableCollection<Semestr> Semesters { get { return semestrs; } }
        public ObservableCollection<Work> Works { get { return works; } } 
        public ObservableCollection<ReqsWork> ReqWorks { get { return reqWorks; } }
        public ObservableCollection<RefReq> RefReqs { get { return refReq; } }
        public ObservableCollection<godUP> Gods { get { return gods; } }
        public ObservableCollection<TypeSem> TypeSems { get { return typeSems; } }
        public ObservableCollection<Discipline> Disciplines { get { return disciplines; } }
        public ObservableCollection<VidWork> VidWorks { get { return vidWorks; } }
        public ObservableCollection<LoadWork> LoadWorks { get { return loadWorks; }}
        


        public MainViewModel()
        {
            client = new RegOnlineService.RegOnlineDPSClient();
            currentUser = new AppUser();
            client.GetPrepodsCompleted += new EventHandler<GetPrepodsCompletedEventArgs>(client_GetPrepodsCompleted);
            client.GetStudentsCompleted += new EventHandler<GetStudentsCompletedEventArgs>(client_GetStudentsCompleted);
            client.GetGrupStudCompleted += new EventHandler<GetGrupStudCompletedEventArgs>(client_GetGrupStudCompleted);
            
            client.GetStudSemAndUchPlanCompleted += new EventHandler<GetStudSemAndUchPlanCompletedEventArgs>(client_GetStudSemAndUchPlanCompleted);
            client.GetWorkCompleted += new EventHandler<GetWorkCompletedEventArgs>(client_GetWorkCompleted);
            client.GetReqWorkANDLoadWorkCompleted += new EventHandler<GetReqWorkANDLoadWorkCompletedEventArgs>(client_GetReqWorkANDLoadWorkCompleted);
            client.GetReqCompleted += new EventHandler<GetReqCompletedEventArgs>(client_GetReqCompleted);
            client.GetGrupPrepodAndUchPlanCompleted += new EventHandler<GetGrupPrepodAndUchPlanCompletedEventArgs>(client_GetGrupPrepodAndUchPlanCompleted);
            client.GetGodUPCompleted += new EventHandler<GetGodUPCompletedEventArgs>(client_GetGodUPCompleted);
            client.GetTypeSemCompleted += new EventHandler<GetTypeSemCompletedEventArgs>(client_GetTypeSemCompleted);
            client.OtchetZarCompleted += new EventHandler<OtchetZarCompletedEventArgs>(client_OtchetZarCompleted);

            client.InsertRefReqCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_InsertRefReqCompleted);
            client.InsertReqWorkCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_InsertReqWorkCompleted);

            client.GetDisCompleted += new EventHandler<GetDisCompletedEventArgs>(client_GetDisCompleted);
            client.GetVidCompleted += new EventHandler<GetVidCompletedEventArgs>(client_GetVidCompleted);
            client.GetReqWorkCompleted += new EventHandler<GetReqWorkCompletedEventArgs>(client_GetReqWorkCompleted);

            client.SaveFileCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_SaveFileCompleted);
            client.DeleteListReqCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_DeleteListReqCompleted);
            client.InsertWorkRegNumCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_InsertWorkRegNumCompleted);
            client.DeleteFileCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_DeleteFileCompleted);
            client.UpdateWorkCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(client_UpdateWorkCompleted);

            client.GetFacultetCompleted += new EventHandler<GetFacultetCompletedEventArgs>(client_GetFacultetCompleted);
            client.GetFioPrepodCompleted += new EventHandler<GetFioPrepodCompletedEventArgs>(client_GetFioPrepodCompleted);
            client.GetKafedraCompleted += new EventHandler<GetKafedraCompletedEventArgs>(client_GetKafedraCompleted);
            client.GetSpecialnostCompleted += new EventHandler<GetSpecialnostCompletedEventArgs>(client_GetSpecialnostCompleted);

            LoadPrepods();
            LoadStudents();
            
        }



        public void GetPrintInfo(int id_up,int id_UspevDoc)
        {
            printFac =false;
            printPrepod =false;
            printSpec =false;
            printKaf = false;


            client.GetFacultetAsync(id_UspevDoc);
            client.GetFioPrepodAsync(id_up);
            client.GetKafedraAsync(id_up);
            client.GetSpecialnostAsync(id_UspevDoc);
        }

        void client_GetFioPrepodCompleted(object sender, GetFioPrepodCompletedEventArgs e)
        {
            PrintFio = e.Result;
            printPrepod = true;
            InvokePrintInfoLoaded(null);

        }
        void client_GetSpecialnostCompleted(object sender, GetSpecialnostCompletedEventArgs e)
        {
            PrintSpec = e.Result;
            printSpec = true;
            InvokePrintInfoLoaded(null);
        }


        public void InvokePrintInfoLoaded(EventArgs e)
        {
            if (!printPrepod) return;
            if (!printSpec) return;
            if (!printFac) return;
            if (!printKaf) return;

            EventHandler handler = PrintInfoLoaded;
            if (handler != null) handler(this, e);
        }



        void client_GetKafedraCompleted(object sender, GetKafedraCompletedEventArgs e)
        {
            PrintKaf = e.Result;
            printKaf = true;
            InvokePrintInfoLoaded(null);
        }

        void client_GetFacultetCompleted(object sender, GetFacultetCompletedEventArgs e)
        {
            PrintFacultet = e.Result;
            printFac = true;
            InvokePrintInfoLoaded(null);
        }

        void client_UpdateWorkCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
        }

        void client_DeleteFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
        }

        void client_InsertWorkRegNumCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {   
            WorksLoaded(sender, e);
        }

        void client_GetReqCompleted(object sender, GetReqCompletedEventArgs e)
        {
            refReq = e.Result;
            RefReqLoaded(sender, e);
        }


        void client_SaveFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            FileSaved(sender, e);
        }

        void client_DeleteListReqCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
        }

        void client_GetReqWorkCompleted(object sender, GetReqWorkCompletedEventArgs e)
        {
            reqWorks = e.Result;
            LoadCompletedInit(typeof(ReqsWork));
            if (ReqWorksLoaded != null) ReqWorksLoaded(this, e);
        }

       
        void client_GetVidCompleted(object sender, GetVidCompletedEventArgs e)
        {
            vidWorks = e.Result;
            currentVidWork = e.Result[0];
            VidWorkLoaded(sender, e);
        }

        void client_GetDisCompleted(object sender, GetDisCompletedEventArgs e)
        {
            disciplines = e.Result;
            CurrentDiscipline = disciplines[0];
            DisciplineLoaded(sender, e);
        }

        void client_OtchetZarCompleted(object sender, OtchetZarCompletedEventArgs e)
        {
            works = e.Result;
            WorksLoaded(sender, e);
        }

        void client_GetTypeSemCompleted(object sender, GetTypeSemCompletedEventArgs e)
        {
            typeSems = e.Result;            
            TypeSemLoaded(sender, e);
        }

        void client_GetGodUPCompleted(object sender, GetGodUPCompletedEventArgs e)
        {
            gods = e.Result;
            GodsLoaded(sender, e);
        }


        public AppUser User
        {
            get
            {
                return currentUser;
            }
            set
            {
                currentUser  =value ;
                LoadCompletedInit(typeof(AppUser));
                UserLoaded(this, null);
            }

        }

        public godUP CurrentGod
        {
            get { return currentGod; }
            set
            {
                currentGod = value;
                LoadCompletedInit(typeof(godUP));
                PropertyChangedInit("CurrentGod");
            }
        }

        public VidWork CurrentVidWork
        {
            get { return currentVidWork; }
            set
            {
                currentVidWork = value;
                LoadCompletedInit(typeof(VidWork));
                PropertyChangedInit("CurrentVidWork");
            }
        }

        public Discipline CurrentDiscipline
        {
            get { return currentDiscipline; }
            set
            {
                currentDiscipline = value;
                LoadCompletedInit(typeof(Discipline));
                PropertyChangedInit("CurrentDiscipline");
            }
        }
        public Group CurrentGroup
        {
            get { return currentGroup; }
            set
            {
                currentGroup = value;
                LoadCompletedInit(typeof(Group));
                PropertyChangedInit("CurrentGroup");
            }
        }
        public Semestr CurrentSemestr
        {
            get { return currentSemestr; }
            set
            {
                currentSemestr = value;
                LoadCompletedInit(typeof(Semestr));
                PropertyChangedInit("CurrentSemestr");
            }
        }
        public UchPlan CurrentUchPlan
        {
            get { return currentUchPlan; }
            set
            {
                currentUchPlan = value;
                CurrentGod = value.GodsUP;
                LoadCompletedInit(typeof(UchPlan));
                PropertyChangedInit("CurrentUchPlan");
            }
        }
        public TypeSem CurrentTypeSem
        {
            get { return currenrTypeSem; }
            set
            {
                currenrTypeSem = value;
                LoadCompletedInit(typeof(TypeSem));
                PropertyChangedInit("CurrenrTypeSem");
            }
        }

        public void SetUser(Object u)
        {
            if (currentUser==null) currentUser = new AppUser();
            currentUser.SetUser(u);
            LoadCompletedInit(typeof(AppUser));
            UserLoaded(this, null);
            
        }

        public ReqsWork CurrentReqWork
        {
            get { return currentReqWork; }
            set
            {
                currentReqWork = value;
                LoadCompletedInit(typeof(ReqsWork));
                PropertyChangedInit("CurrentReqWork");
            }

        }

        public RefReq CurrentRefReq
        {
            get { return currentRefReq; }
            set
            {
                currentRefReq = value;
                LoadCompletedInit(typeof(RefReq));
                PropertyChangedInit("CurrentRefReq");
            }

        }

        public LoadWork CurrentLoadWork
        {
            get { return currentLoadWork; }
            set
            {
                currentLoadWork = value;
                LoadCompletedInit(typeof(LoadWork));
                PropertyChangedInit("CurrentLoadWork");
            }

        }

        public Work CurrentWork
        {
            get { return currentWork; }
            set
            {
                currentWork = value;
                LoadCompletedInit(typeof(Work));
                PropertyChangedInit("CurrentWork");
            }

        }


        

        #region EventHandlerCalls


        void client_GetGrupPrepodAndUchPlanCompleted(object sender, GetGrupPrepodAndUchPlanCompletedEventArgs e)
        {
            grups = e.Result;

            try
            {
                currentGroup = e.Result[0];
               
            }
            catch (Exception)
            {
                
            }
            finally
            {
                LoadCompletedInit(typeof(Group));
                if (PrepodGrupsLoaded != null) PrepodGrupsLoaded(this, e);                
            }

        }

        void client_InsertRefReqCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
        }

        void client_GetStudentsCompleted(object sender, GetStudentsCompletedEventArgs e)
        {
            students = e.Result;
            LoadCompletedInit(typeof(Student));
            if (StudentLoaded != null) StudentLoaded(this, e);
        }

        void client_GetPrepodsCompleted(object sender, GetPrepodsCompletedEventArgs e)
        {
            prepods = e.Result;
            LoadCompletedInit(typeof(Prepod));
            if (PrepodsLoaded != null) PrepodsLoaded(this, e);
        }

        void client_GetGrupStudCompleted(object sender, GetGrupStudCompletedEventArgs e)
        {
            grups = e.Result;
            currentGroup = e.Result[0];
            LoadCompletedInit(typeof(Group));
            if (GroupLoaded != null) GroupLoaded(this, e);
        }

        void client_GetStudSemAndUchPlanCompleted(object sender, GetStudSemAndUchPlanCompletedEventArgs e)
        {
            semestrs = e.Result;
            LoadCompletedInit(typeof(Semestr));
            if (SemetrLoaded != null) SemetrLoaded(this, e);
        }

        void client_GetReqWorkANDLoadWorkCompleted(object sender, GetReqWorkANDLoadWorkCompletedEventArgs e)
        {
            reqWorks = e.Result;
            LoadCompletedInit(typeof(ReqsWork));
            if (ReqWorksLoaded != null) ReqWorksLoaded(this, e);
        }

        void client_GetWorkCompleted(object sender, GetWorkCompletedEventArgs e)
        {
            works = e.Result;
            if (works.Count != 0) currentWork = works[0];
                else currentWork = null;

            LoadCompletedInit(typeof(Work));
            if (WorksLoaded != null) WorksLoaded(this, e);
        }

        void client_InsertReqWorkCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            //ReqWorkIserted(this, e);
        }



        #endregion





        #region LoadersProcedures

        public void InsertReqWork(int? IdRefReq, string expdoc)
        {
            try
            {
                var i = int.Parse(currentGod.NameGod.ToString());
                client.InsertReqWorkAsync(i, (int)currentUchPlan.IdUP, (int)IdRefReq, expdoc);
            }
            catch (Exception ex)
            {
                ErrorWindow errorWindow = new ErrorWindow(ex);
                errorWindow.Show();
            }
        }


        public void LoadGrupPrepod(int IdTypeSem)
        {
            try
            {
                client.GetGrupPrepodAndUchPlanAsync(currentGod.IdGod, IdTypeSem, currentUser.IdUser);

            }
            catch (Exception)
            {
                
                
            }
        }

        public void LoadStudents()
        {
            try
            {
                client.GetStudentsAsync();

            }
            catch (Exception)
            {
                
            }
        }

        public void LoadPrepods()
        {
            client.GetPrepodsAsync();
        }

        public void LoadOtchet(int IdGod, int IdTypeSem, int? IdGrup, int IdUser, int? IdDis, int? IdVid, DateTime from, DateTime to)
        {
            try
            {
                client.OtchetZarAsync(currentGod.IdGod, CurrentTypeSem.IdTypeSem, (int)currentGroup.IdGrup, User.IdUser, (int)currentDiscipline.IdDis, (int)currentVidWork.IdVid, from, to);

            }
            catch (Exception)
            {

            }
        }



        public void LoadDiscipline(int IdGod, int IdTypeSem, int? IdGrup, int IdUser)
        {
            try
            {
                client.GetDisAsync(currentGod.IdGod, CurrentTypeSem.IdTypeSem, (int)CurrentGroup.IdGrup, currentUser.IdUser);

            }
            catch (Exception)
            {

                return;
            }
        }




        public void LoadGroupStudent()
        {
            try
            {
                client.GetGrupStudAsync(currentUser.IdUser);

            }
            catch (Exception)
            {
                
            }
        }

        public void LoadSemestr(int idGroup)
        {
            try
            {
                client.GetStudSemAndUchPlanAsync(currentUser.IdUser, idGroup);

            }
            catch (Exception)
            {
                
            }
        }

        public void LoadWork(int idDisc, int idVid)
        {
            try
            {
                client.GetWorkAsync(idDisc, idVid, (int)currentSemestr.SemNum, User.IdUser);

            }
            catch (Exception)
            {
                
            }

        }

        public void LoadReqWork(int idDisc, int idVid)
        {
            try
            {
                client.GetReqWorkANDLoadWorkAsync(idDisc, idVid, (int)currentSemestr.SemNum, User.IdUser);

            }
            catch (Exception)
            {
                
            }

        }

        public void LoadWork()
        {
            try
            {
                client.GetWorkAsync((int)currentUchPlan.Dis.IdDis, (int)CurrentUchPlan.Vid.IdVid, (int)currentSemestr.SemNum, User.IdUser);

            }
            catch (Exception)
            {

            }
        }

        public void LoadReqWork()
        {
            try
            {
                client.GetReqWorkANDLoadWorkAsync((int)currentUchPlan.Dis.IdDis, (int)CurrentUchPlan.Vid.IdVid, (int)currentSemestr.SemNum, User.IdUser);

            }
            catch (Exception)
            {
                
            }

        }

        public void LoadReqWorkForPrepod(int IdGod, int IdTypeSem, int? idDis, int? idVid)
        {
            try
            {
                client.GetReqWorkAsync(IdGod, IdTypeSem, (int)CurrentDiscipline.IdDis, (int)CurrentVidWork.IdVid, (int)currentGroup.IdGrup, User.IdUser);

            }
            catch (Exception)
            {

            }

        }

        public void InsertRefReqAsync(string NR)
        {
            client.InsertRefReqAsync(NR);
        }



        public void LoadGodUP()
        {
            client.GetGodUPAsync();
        }

        public void LoadTypeSem()
        {
            client.GetTypeSemAsync();
        }
        #endregion




        public void DeleteListReq(ReqsWork r)
        {
            try
            {
                client.DeleteListReqAsync((int)r.IdListReq);
            }
            catch (Exception)
            {

            }

        }

        public void DeleteResultWork(int? SistemNum)
        {
            try
            {
                client.DeleteFileAsync((int)SistemNum);
            }
            catch (Exception)
            {
            }
        }

        public void InsertWorkTheme (Work w)
        {
            try

            {
                client.InsertWorkThemeAsync((int)currentUchPlan.IdUP, User.GetAsStudent().zach.IdZach , (decimal?)w.options, w.theme);
            }
            catch (Exception)
            {

            }

        }


        public void LoadVidWork(int IdGod, int IdTypeSem, int? IdGrup, int? IdDis, int? IdUser)
        {
            try
            {
                client.GetVidAsync(currentGod.IdGod, currenrTypeSem.IdTypeSem, (int)currentGroup.IdGrup, (int)CurrentDiscipline.IdDis, (int)User.IdUser);

            }
            catch (Exception)
            {

            }
        }

        public void SaveFile(byte[] load)

        {
           client.SaveFileAsync((int)currentReqWork.IdListReq, (int)currentWork.IdWork, load); 
           
        }


        public void LoadReq()
        {
            try
            {
                client.GetReqAsync();

            }
            catch (Exception)
            {

            }

        }

        public void InsertWorkNum()
        {
            try
            {

            client.InsertWorkRegNumAsync((int)currentWork.IdWork);

            }
            catch (Exception)
            {

            }

        }

        public void UpdateWork()
        {
            try
            {

                client.UpdateWorkAsync((int)currentWork.IdWork, currentWork.theme, currentWork.options);

            }
            catch (Exception)
            {

            }

        }

        
    }

}